﻿using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HPDI.DrawingStandard
{
    public static class LayoutTools
    {

        #region 布局
        public static ObjectId CreatLayout(this Database db, string Name, string TKPath, bool isA1 = false, int NumPDF = 1)
        {
            ObjectId curLayId;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary lays = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForWrite) as DBDictionary;

                if (!lays.Contains(Name))
                {
                    curLayId = LayoutManager.Current.CreateLayout(Name);
                }
                else
                {
                    LayoutManager.Current.DeleteLayout(Name);
                    curLayId = LayoutManager.Current.CreateLayout(Name);
                    //curLayId = LayoutManager.Current.GetLayoutId(Name);
                }
                for (int page = 0; page < NumPDF; page++)
                {
                    if (isA1)
                        db.XrefAttachAndInsert(TKPath, curLayId, Point3d.Origin.C3D(page * 841));
                    else
                        db.XrefAttachAndInsert(TKPath, curLayId, Point3d.Origin.C3D(page * 420));
                }
                LayoutManager.Current.CurrentLayout = Name;
                var lay = (Layout)tr.GetObject(curLayId, OpenMode.ForWrite);
                if (!isA1)
                    lay.SetPlotSettings("ISO_full_bleed_A3_(420.00_x_297.00_MM)", "monochrome.ctb", "DWG To PDF.pc3");
                else
                    lay.SetA1PlotSettings("ISO_full_bleed_A1_(841.00_x_594.00_MM)", "monochrome.ctb", "DWG To PDF.pc3");
                tr.Commit();
            }
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                LayoutManager LM = LayoutManager.Current;
                DBDictionary LayoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
                Layout CurrentLo = tr.GetObject(curLayId, OpenMode.ForRead) as Layout;
                BlockTableRecord BlkTblRec = tr.GetObject(CurrentLo.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
                foreach (ObjectId ID in BlkTblRec)
                {
                    Viewport VP = tr.GetObject(ID, OpenMode.ForRead) as Viewport;
                    if (VP != null)
                    {
                        VP.UpgradeOpen();
                        VP.Erase();
                    }
                }

                if (LM.LayoutExists("布局1"))
                {
                    LM.DeleteLayout("布局1");
                }
                if (LM.LayoutExists("布局2"))
                {
                    LM.DeleteLayout("布局2");
                }
                if (LM.LayoutExists("layout1"))
                {
                    LM.DeleteLayout("layout1");
                }
                if (LM.LayoutExists("layout2"))
                {
                    LM.DeleteLayout("layout2");
                }
                LM.CurrentLayout = "Model";

                tr.Commit();
            }

            return curLayId;
        }

        /// <summary>
        /// 引入并插入参照
        /// </summary>
        /// <param name="db"></param>
        /// <param name="path"></param>
        /// <param name="paperSpaceId"></param>
        /// <param name="pos"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool XrefAttachAndInsert(this Database db, string path, ObjectId paperSpaceId, Point3d pos, string name = null)
        {
            var ret = false;
            if (!File.Exists(path))
                return ret;

            if (String.IsNullOrEmpty(name))
                name = Path.GetFileNameWithoutExtension(path);

            try
            {
                using (var tr = db.TransactionManager.StartOpenCloseTransaction())
                {
                    var xId = db.AttachXref(path, name);
                    if (xId.IsValid)
                    {
                        Layout tmp = (Layout)tr.GetObject(paperSpaceId, OpenMode.ForWrite);
                        var btr = (BlockTableRecord)tr.GetObject(tmp.BlockTableRecordId, OpenMode.ForWrite);
                        var br = new BlockReference(pos, xId);
                        btr.AppendEntity(br);
                        tr.AddNewlyCreatedDBObject(br, true);
                        ret = true;
                    }
                    tr.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception)
            { }

            return ret;
        }


        public static void SetPlotSettings(this Layout lay, string pageSize, string styleSheet, string device)
        {
            using (var ps = new PlotSettings(lay.ModelType))
            {
                ps.CopyFrom(lay);
                var psv = PlotSettingsValidator.Current;
                // Set the device
                var devs = psv.GetPlotDeviceList();
                if (devs.Contains(device))
                {
                    psv.SetPlotConfigurationName(ps, device, null);
                    psv.RefreshLists(ps);
                }
                // Set the media name/size
                var mns = psv.GetCanonicalMediaNameList(ps);
                if (mns.Contains(pageSize))
                {
                    psv.SetCanonicalMediaName(ps, pageSize);
                }
                psv.SetPlotWindowArea(ps, new Extents2d(new Point2d(0, 0), new Point2d(420, 297)));
                //psv.SetPlotRotation(ps, PlotRotation.Degrees000);//设置横向;纵向Degrees270

                //psv.SetStdScale(ps, 1);
                //psv.SetPlotType(ps, PlotType.Layout);//设置打印范围

                psv.RefreshLists(ps);
                psv.SetPlotRotation(ps, PlotRotation.Degrees000);

                //psv.SetPlotCentered(ps, true);
                psv.SetCustomPrintScale(ps, new CustomScale(1, 1));
                psv.SetPlotType(ps, PlotType.Window);
                psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters);//设置的单位
                psv.SetStdScaleType(ps, StdScaleType.StdScale1To1);//设置比例
                //psv.SetPlotCentered(ps, true);
                // Set the pen settings
                var ssl = psv.GetPlotStyleSheetList();
                if (ssl.Contains(styleSheet))
                {
                    psv.SetCurrentStyleSheet(ps, styleSheet);
                }
                // Copy the PlotSettings data back to the Layout

                var upgraded = false;
                if (!lay.IsWriteEnabled)
                {
                    lay.UpgradeOpen();
                    upgraded = true;
                }
                lay.CopyFrom(ps);
                if (upgraded)
                {
                    lay.DowngradeOpen();
                }
            }
        }


        public static void SetA1PlotSettings(this Layout lay, string pageSize, string styleSheet, string device)
        {
            using (var ps = new PlotSettings(lay.ModelType))
            {

                ps.CopyFrom(lay);
                var psv = PlotSettingsValidator.Current;
                // Set the device
                var devs = psv.GetPlotDeviceList();
                if (devs.Contains(device))//设置设备
                {
                    psv.SetPlotConfigurationName(ps, device, null);
                    psv.RefreshLists(ps);
                }
                // Set the media name/size
                var mns = psv.GetCanonicalMediaNameList(ps);

                if (mns.Contains(pageSize))//设置纸张大小
                {
                    psv.SetCanonicalMediaName(ps, pageSize);
                }
                //psv.SetPlotWindowArea(ps, new Extents2d(new Point2d(0, 0), new Point2d(841, 594)));//设置打印纸张大小范围
                //                                                                                   //psv.SetPlotType(ps, PlotType.Window);//设置打印范围
                //                                                                                   //psv.SetStdScale(ps, 1);//设置标准比例

                //psv.SetCustomPrintScale(ps, new CustomScale(1, 1));
                //psv.SetUseEnScale(ps, true);
                psv.SetStdScaleType(ps, StdScaleType.StdScale1To1);//设置比例
                psv.SetPlotPaperUnits(ps, PlotPaperUnit.Millimeters);//设置的单位
                //psv.SetPlotRotation(ps, PlotRotation.Degrees000);//设置横向;纵向Degrees270

                //psv.SetStdScale(ps, 1);
                //psv.SetPlotType(ps, PlotType.Layout);//设置打印范围

                psv.RefreshLists(ps);
                psv.SetPlotRotation(ps, PlotRotation.Degrees000);
                psv.SetCustomPrintScale(ps, new CustomScale(1, 1));
                psv.SetPlotWindowArea(ps, new Extents2d(1, 0, 841, 594));
                psv.SetPlotType(ps, PlotType.Window);
                var ssl = psv.GetPlotStyleSheetList();
                if (ssl.Contains(styleSheet))
                {
                    psv.SetCurrentStyleSheet(ps, styleSheet);
                    //psv.
                }
                // Copy the PlotSettings data back to the Layout

                var upgraded = false;
                if (!lay.IsWriteEnabled)
                {
                    lay.UpgradeOpen();
                    upgraded = true;
                }
                lay.CopyFrom(ps);
                if (upgraded)
                {
                    lay.DowngradeOpen();
                }
            }
        }
        #endregion

        #region  视口
        public static void CreateViewport(Database db, ObjectId LayoutId, double W, double L, Point2d PSCenter, Point2d MSCenter, int scale)
        {
            using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
            {
                Layout lay = (Layout)tr.GetObject(LayoutId, OpenMode.ForWrite);
                UcsTable ut = tr.GetObject(db.UcsTableId, OpenMode.ForWrite) as UcsTable;
                var btr = (BlockTableRecord)tr.GetObject(lay.BlockTableRecordId, OpenMode.ForWrite);

                // 平面视口
                Viewport vpFlat = new Viewport();
                btr.AppendEntity(vpFlat);
                tr.AddNewlyCreatedDBObject(vpFlat, true);
                vpFlat.Layer = "图框";
                vpFlat.On = true;
                vpFlat.GridOn = false;
                vpFlat.SettingSizeAndLoc(W, L, PSCenter, scale);
                vpFlat.ViewCenter = MSCenter;
                vpFlat.Visible = true;
                //viewCenter = vpFlat.ViewCenter;
                //vpFlat.ViewCenter = new Point2d((pt.X+ offset+ offsetY + areaWidth) /2, (pt.Y + areaHeight) /2);
                tr.Commit();
            }
            return;
        }

        public static void CreateViewportRotate(Database db, ObjectId LayoutId, double W,
            double L, Point2d PSCenter, Point2d MSCenter, int scale, double angle = 90)
        {
            using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
            {
                Layout lay = (Layout)tr.GetObject(LayoutId, OpenMode.ForWrite);
                UcsTable ut = tr.GetObject(db.UcsTableId, OpenMode.ForWrite) as UcsTable;
                var btr = (BlockTableRecord)tr.GetObject(lay.BlockTableRecordId, OpenMode.ForWrite);

                // 平面视口
                Viewport vpFlat = new Viewport();
                btr.AppendEntity(vpFlat);
                tr.AddNewlyCreatedDBObject(vpFlat, true);
                vpFlat.Layer = "图框";
                vpFlat.On = true;
                vpFlat.GridOn = false;
                vpFlat.SettingSizeAndLoc(W, L, PSCenter, scale);
                vpFlat.ViewCenter = MSCenter;
                vpFlat.Visible = false;

                vpFlat.TwistAngle = GeTools.DegreeToRadian(angle);
                //viewCenter = vpFlat.ViewCenter;
                //vpFlat.ViewCenter = new Point2d((pt.X+ offset+ offsetY + areaWidth) /2, (pt.Y + areaHeight) /2);
                tr.Commit();
            }
            return;
        }

        /// <summary>
        /// 平面\立面视口.
        /// </summary>
        public static void SettingSizeAndLoc(this Viewport vp, double w, double h, Point2d basepoint, double scale)
        {
            vp.Width = w;
            vp.Height = h;
            vp.CenterPoint = basepoint.C3D();
            vp.CustomScale = 1.0 / scale;
            vp.Locked = false;
        }

        /// <summary>
        /// 上二下二四视口布局
        /// </summary>
        /// <param name="db"></param>
        /// <param name="layoutName"></param>
        /// <param name="extTL">上部左侧对应的范围</param>
        /// <param name="extTR">上部右侧对应的范围</param>
        /// <param name="extBL">下部左侧对应的范围</param>
        /// <param name="extBR">上部右侧对应的范围</param>
        /// <param name="MarginL">图框左侧边距</param>
        /// <param name="MarginR">图框右侧边距</param>
        /// <param name="MarginB">图框底部边距</param>
        /// <param name="MarginT">图框顶部边距</param>
        /// <param name="scale">对应比例尺</param>
        /// <param name="isA1">A1或者A3图框</param>
        /// <param name="tkPath"></param>
        /// <returns></returns>
        public static ObjectId CreateLayout4Div(Database db, string layoutName,
         Extents2d extTL, Extents2d extTR, Extents2d extBL, Extents2d extBR,
         double MarginL, double MarginR, double MarginB, double MarginT, double scale, bool isA1 = false, string tkPath = "")
        {
            ObjectId ArrangeLayoutId;
            if (System.IO.File.Exists(tkPath))
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, tkPath, isA1, 1);
            }
            else
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, "", isA1, 1);
            }

            double VPWidth1 = Math.Max(extTL.W(), extBL.W()) / scale;
            double VPHight1 = Math.Max(extTL.L(), extTR.L()) / scale;
            double w = (420 - MarginL - MarginR);
            double h = (297 - MarginB - MarginT);

            double wA = w * (extTL.W() / (extTL.W() + extTR.W()));  //上部左侧视口长度
            double wB = w * (extTR.W() / (extTL.W() + extTR.W()));  //上部右侧视口长度
            double hA = h * (extTL.L() / (extTL.L() + extBL.L()));  //上部左侧视口高度
            double hP = h * (extBL.L() / (extTL.L() + extBL.L()));  //下部左侧视口高度

            double M1 = MarginL + wA;  //上部右侧视口位置
            double M2 = MarginB + hP;  //上部右侧视口位置

            CreateViewport(db, ArrangeLayoutId, extTL.W() / scale + 5, extTL.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + wA * 0.5, M2 + 0.5 * hA),
                extTL.GetCenter(), (int)scale);

            CreateViewport(db, ArrangeLayoutId, extTR.W() / scale + 5, extTR.L() / scale + 5,
                Point2d.Origin.C2D(M1 + wB * 0.5, M2 + 0.5 * hA),
                extTR.GetCenter(), (int)scale);

            CreateViewport(db, ArrangeLayoutId, extBL.W() / scale + 5, extBL.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + 0.5 * wA, MarginB + 0.5 * hP),
                extBL.GetCenter(), (int)scale);


            CreateViewport(db, ArrangeLayoutId, extBR.W() / scale + 5, extBR.L() / scale + 5,
            Point2d.Origin.C2D(M1 + wB * 0.5, MarginB + 0.5 * hP),
            extBR.GetCenter(), (int)scale);

            return ArrangeLayoutId;
        }
        /// <summary>
        /// 自动创建上中下三视口布局
        /// </summary>
        /// <param name="db"></param>
        /// <param name="layoutName">布局名称</param>
        /// <param name="extT">上部视口对应的范围</param>
        /// <param name="extM">中部视口对应的范围</param>
        /// <param name="extB">下部视口对应的范围</param>
        /// <param name="MarginL">图框左侧边距</param>
        /// <param name="MarginR">图框右侧边距</param>
        /// <param name="MarginB">图框底部边距</param>
        /// <param name="MarginT">图框顶部边距</param>
        /// <param name="scale">对应比例尺</param>
        /// <param name="isA1">A1或者A3图框</param>
        /// <returns></returns>

        public static ObjectId CreateLayout3Div(Database db, string layoutName,
               Extents2d extT, Extents2d extM, Extents2d extB,
               double MarginL, double MarginR, double MarginB, double MarginT, double scale,bool isA1=false, string tkPath = "")
        {
            ObjectId ArrangeLayoutId;
          
            if (System.IO.File.Exists(tkPath))
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, tkPath, isA1, 1);
            }
            else
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, "", isA1, 1);
            }
           
            double w = (420 - MarginL - MarginR);
            double h = (297 - MarginB - MarginT);
            double hA = h * (extT.L() / (extT.L() + extM.L() + extB.L()));  //上部视口高度
            double hP = h * (extM.L() / (extT.L() + extM.L() + extB.L()));  //中部视口高度
            double hD = h * (extB.L() / (extT.L() + extM.L() + extB.L()));  //下部视口高度

            CreateViewport(db, ArrangeLayoutId, extT.W() / scale + 5, extT.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + w * 0.5, MarginB + hD + hP + 0.5 * hA),
                extT.GetCenter(), (int)scale);

            CreateViewport(db, ArrangeLayoutId, extM.W() / scale + 5, extM.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + w * 0.5, MarginB + hD + 0.5 * hP),
                extM.GetCenter(), (int)scale);

            CreateViewport(db, ArrangeLayoutId, extB.W() / scale + 5, extB.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + 0.5 * w, MarginB + 0.5 * hD),
                extB.GetCenter(), (int)scale);

            return ArrangeLayoutId;
        }

        /// <summary>
        /// 左中右三视口
        /// </summary>
        /// <param name="db"></param>
        /// <param name="layoutName"></param>
        /// <param name="extL">左部视口对应的范围</param>
        /// <param name="extM">中部视口对应的范围</param>
        /// <param name="extR">右部视口对应的范围</param>
        /// <param name="MarginL">图框左侧边距</param>
        /// <param name="MarginR">图框右侧边距</param>
        /// <param name="MarginB">图框底部边距</param>
        /// <param name="MarginT">图框顶部边距</param>
        /// <param name="scale">对应比例尺</param>
        /// <param name="isA1">A1或者A3图框</param>
        /// <returns></returns>
        public static ObjectId CreateLRLayout3Div(Database db, string layoutName,
             Extents2d extL, Extents2d extM, Extents2d extR,
             double MarginL, double MarginR, double MarginB, double MarginT, double scale, bool isA1 = false, string tkPath = "")
        {
            ObjectId ArrangeLayoutId;
            if (System.IO.File.Exists(tkPath))
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, tkPath, isA1, 1);
            }
            else
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, "", isA1, 1);
            }

            double w = (420 - MarginL - MarginR);
            double h = (297 - MarginB - MarginT);
            double wL= h * (extL.L() / (extL.L() + extM.L() + extR.L()));  //左部视口高度
            double wM = h * (extM.L() / (extL.L() + extM.L() + extR.L()));  //中部视口高度
            double wR = h * (extR.L() / (extL.L() + extM.L() + extR.L()));  //右部视口高度

            CreateViewport(db, ArrangeLayoutId, extL.W() / scale + 5, extL.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + wL * 0.5, MarginB + 0.5 * h),
                extL.GetCenter(), (int)scale);

            CreateViewport(db, ArrangeLayoutId, extM.W() / scale + 5, extM.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + wL+wM * 0.5, MarginB +  0.5 * h),
                extM.GetCenter(), (int)scale);

            CreateViewport(db, ArrangeLayoutId, extR.W() / scale + 5, extR.L() / scale + 5,
                Point2d.Origin.C2D(MarginL+ wL+wM + 0.5 * w, MarginB + 0.5 * h),
                extR.GetCenter(), (int)scale);

            return ArrangeLayoutId;
        }

        /// <summary>
        /// 自动创建上下二视口布局
        /// </summary>
        /// <param name="db"></param>
        /// <param name="layoutName">布局名称</param>
        /// <param name="extT">上部视口对应的范围</param>
        /// <param name="extB">下部视口对应的范围</param>
        /// <param name="MarginL">图框左侧边距</param>
        /// <param name="MarginR">图框右侧边距</param>
        /// <param name="MarginB">图框底部边距</param>
        /// <param name="MarginT">图框顶部边距</param>
        /// <param name="scale">对应比例尺</param>
        /// <param name="isA1">A1或者A3图框</param>
        /// <returns></returns>
        public static ObjectId CreateLayout2Div(Database db, string layoutName,
       Extents2d extT,  Extents2d extB,
       double MarginL, double MarginR, double MarginB, double MarginT, double scale, bool isA1 = false, string tkPath = "")
        {
            ObjectId ArrangeLayoutId;
          
            if (System.IO.File.Exists(tkPath))
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, tkPath, isA1, 1);
            }
            else
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, "", isA1, 1);
            }

            double w = (420 - MarginL - MarginR);
            double h = (297 - MarginB - MarginT);
            double hT = h * (extT.L() / (extT.L()  + extB.L()));  //上部视口高度          
            double hD = h * (extB.L() / (extT.L()  + extB.L()));  //下部视口高度

            CreateViewport(db, ArrangeLayoutId, extT.W() / scale + 5, extT.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + w * 0.5, MarginB + hD  + 0.5 * hT),
                extT.GetCenter(), (int)scale);


            CreateViewport(db, ArrangeLayoutId, extB.W() / scale + 5, extB.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + 0.5 * w, MarginB + 0.5 * hD),
                extB.GetCenter(), (int)scale);

            return ArrangeLayoutId;
        }

        /// <summary>
        /// 自动创建左右二视口布局
        /// </summary>
        /// <param name="db"></param>
        /// <param name="layoutName">布局名称</param>
        /// <param name="extL">左侧视口对应的范围</param>
        /// <param name="extR">右侧视口对应的范围</param>
        /// <param name="MarginL">图框左侧边距</param>
        /// <param name="MarginR">图框右侧边距</param>
        /// <param name="MarginB">图框底部边距</param>
        /// <param name="MarginT">图框顶部边距</param>
        /// <param name="scale">对应比例尺</param>
        /// <param name="isA1">A1或者A3图框</param>
        /// <returns></returns>
        public static ObjectId CreateLRLayout2Div(Database db, string layoutName,
       Extents2d extL, Extents2d extR,
       double MarginL, double MarginR, double MarginB, double MarginT, double scale, bool isA1 = false, string tkPath = "")
        {
            ObjectId ArrangeLayoutId;
            if (System.IO.File.Exists(tkPath))
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, tkPath, isA1, 1);
            }
            else
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, "", isA1, 1);
            }

            double w = (420 - MarginL - MarginR);
            double h = (297 - MarginB - MarginT);
            double wL  = w * (extL.W() / (extL.W() + extR.W()));  //上部视口高度          
            double wR  = w * (extR.W() / (extL.W() + extR.W()));  //下部视口高度

            CreateViewport(db, ArrangeLayoutId, extL.W() / scale + 5, extL.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + wL * 0.5, MarginB + 0.5 * h),
                extL.GetCenter(), (int)scale);


            CreateViewport(db, ArrangeLayoutId, extR.W() / scale + 5, extR.L() / scale + 5,
                Point2d.Origin.C2D(MarginL + wL+ 0.5 * wR, MarginB + 0.5 * h),
                extR.GetCenter(), (int)scale);

            return ArrangeLayoutId;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="db"></param>
        /// <param name="layoutName"></param>
        /// <param name="ext">对应的范围</param>
        /// <param name="MarginL">图框左侧边距</param>
        /// <param name="MarginR">图框右侧边距</param>
        /// <param name="MarginB">图框底部边距</param>
        /// <param name="MarginT">图框顶部边距</param>
        /// <param name="scale">对应比例尺</param>
        /// <param name="isA1">A1或者A3图框</param>
        /// <param name="tkPath"></param>
        /// <returns></returns>
        public static ObjectId CreateLayout(Database db, string layoutName,
Extents2d ext, double MarginL, double MarginR, double MarginB, double MarginT, double scale, bool isA1 = false, string tkPath = "")
        {
            ObjectId ArrangeLayoutId;
            if (System.IO.File.Exists(tkPath))
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, tkPath, isA1, 1);
            }
            else
            {
                ArrangeLayoutId = db.CreatLayout(layoutName, "", isA1, 1);
            }

            double w = (420 - MarginL - MarginR);
            double h = (297 - MarginB - MarginT);
            

            CreateViewport(db, ArrangeLayoutId, ext.W() / scale + 5, ext.L() / scale + 5,
                Point2d.Origin.C2D(MarginL +  0.5 * w, MarginB + 0.5 * h),
                ext.GetCenter(), (int)scale);

            return ArrangeLayoutId;
        }

        public static ObjectId CreateLayout(Database db, string layoutName, bool isNullLayout = false, int pdfNum = 1, bool isTitleTab = true, bool isA1 = false)
        {
            ObjectId ArrangeLayoutId;
            ArrangeLayoutId = db.CreatLayout(layoutName, "", isA1, pdfNum);
            return ArrangeLayoutId;
        }
        #endregion
    }
}
